#include "srtransactionwidget.h"

#include <string>

#include <QMap>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QScrollArea>

SRTransactionWidget::SRTransactionWidget(QWidget *parent) : QWidget(parent)
{
    setWindowTitle(tr("详情记录"));
    setFixedSize(1100,600);
    setWindowFlags(/*Qt::FramelessWindowHint | */Qt::Tool );


    QHBoxLayout* layout = new QHBoxLayout();
    QVBoxLayout * layout_vin = new QVBoxLayout();
    QVBoxLayout * layout_vout = new QVBoxLayout();
    QHBoxLayout* layout_vin_title = new QHBoxLayout();
    QHBoxLayout* layout_vout_title = new QHBoxLayout();
    wdgtVin_ = new QWidget();
    wdgtVout_ = new QWidget();
    layoutVin_ = new QVBoxLayout();
    layoutVout_ = new QVBoxLayout();
    labVinTitle_ = new QLabel();
    labVinSumMoney_ = new QLabel();
    labVoutTitle_ = new QLabel();
    labVoutSumMoney_ = new QLabel();
    QWidget* wdgt_vin_title = new QWidget();
    QWidget* wdgt_vout_title = new QWidget();

    wdgt_vin_title->setObjectName("vin_title");
    labVinTitle_->setObjectName("vin_title");
    labVinSumMoney_->setObjectName("vin_title");
    wdgt_vout_title->setObjectName("vout_title");
    labVoutTitle_->setObjectName("vout_title");
    labVoutSumMoney_->setObjectName("vout_title");


    wdgt_vin_title->setFixedWidth(500);
    wdgt_vout_title->setFixedWidth(500);
    wdgtVin_->setFixedWidth(500);
    wdgtVout_->setFixedWidth(500);
    layoutVin_->setMargin(0);
    layoutVout_->setMargin(0);

    // 地址列表
    wdgtVin_->setLayout(layoutVin_);
    wdgtVout_->setLayout(layoutVout_);

    // 标题
    layout_vin_title->addStretch(30);
    layout_vin_title->addWidget(labVinTitle_,0,Qt::AlignLeft);
    layout_vin_title->addWidget(labVinSumMoney_, 400, Qt::AlignRight);
    layout_vin_title->addStretch(30);
    layout_vout_title->addStretch(30);
    layout_vout_title->addWidget(labVoutTitle_,0,Qt::AlignLeft);
    layout_vout_title->addWidget(labVoutSumMoney_, 400, Qt::AlignRight);
    layout_vout_title->addStretch(30);
    wdgt_vin_title->setLayout(layout_vin_title);
    wdgt_vout_title->setLayout(layout_vout_title);

    // 输入列
    layout_vin->addWidget(wdgt_vin_title,0,Qt::AlignTop);
    layout_vin->addWidget(wdgtVin_,1,Qt::AlignTop);
    // 输出列
    layout_vout->addWidget(wdgt_vout_title,0,Qt::AlignTop);
    layout_vout->addWidget(wdgtVout_,1,Qt::AlignTop);

    // 总布局
    layout->addLayout(layout_vin);
    QLabel* lab_arrows = new QLabel();
    lab_arrows->setPixmap(QPixmap(":/business/transaction/arrows"));
    layout->addWidget(lab_arrows);
//    layout->addStretch(30);
    layout->addLayout(layout_vout);



    // @marker: 因为登录界面比较简单，没有外窗口
    //          所以这边模拟了一个外窗口
    QScrollArea *pArea= new QScrollArea();
    mainWdgt= new QWidget(pArea);
    pArea->setWidget(mainWdgt);
    mainWdgt->setGeometry(0,0,width()-30,0);
//    pArea->setFixedHeight(100);

    mainWdgt->setLayout(layout);

//    QGridLayout* temp_layout1 = new QGridLayout();
//    temp_layout1->addWidget(main_wdgt);
//    pArea->setLayout(temp_layout1);


    QGridLayout* temp_layout = new QGridLayout();
    temp_layout->setMargin(0);
    temp_layout->addWidget(pArea);
    setLayout(temp_layout);


}

void SRTransactionWidget::setAuditId(const QString &_auditId) {
    auditId_ = _auditId;
}

void SRTransactionWidget::setAuditData(const QString &_data) {
//    auditData_ = _data;
    QString analysis_data = modifyAuditDataValueToString(_data);
    // 解析 data
    QString txid = "";
    qlonglong tip = 0;
    int vin_size = 0, vout_size = 0;
    qlonglong vin_sum_money = 0, vout_sum_money = 0;
    mapVin_.clear();
    mapVout_.clear();
    listVinWidget_.clear();
    listVoutWidget_.clear();


    QJsonParseError jsonError;
    QJsonDocument doucment = QJsonDocument::fromJson(analysis_data.toUtf8(), &jsonError);
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {
        if (doucment.isObject()) {
            QJsonObject object = doucment.object();

            if (object.contains("txid")) {
                txid = object.value("txid").toString();
            }


            if (object.contains("vin")) {
                QJsonArray vin_arr = object.value("vin").toArray();
                if (!vin_arr.isEmpty()) {
                    vin_size = vin_arr.size();
                    for (int i = 0; i < vin_size; ++i) {
                        QJsonObject temp_single_vin = vin_arr.at(i).toObject();
                        QString temp_money = "";
                        QString temp_vin_addr = "";
                        if (temp_single_vin.contains("value")) {
                            temp_money = temp_single_vin.value("value").toString("");
                            vin_sum_money += temp_money.toLongLong();
                        }
                        if (temp_single_vin.contains("addr")) {
                            temp_vin_addr = temp_single_vin.value("addr").toString();

                        }
#ifdef QT_DEBUG
                        qDebug() << temp_vin_addr << ":" << temp_money;
#endif
                        mapVin_.insert(std::pair<QString,QString>(temp_vin_addr, temp_money));
                    }
                }
            }

            if (object.contains("vout")) {
                QJsonArray vout_arr = object.value("vout").toArray();
                if (!vout_arr.isEmpty()) {
                    vout_size = vout_arr.size();
                    for (int i = 0; i < vout_size; ++i) {
                        QJsonObject temp_single_vout = vout_arr.at(i).toObject();
                        QString temp_money = "";
                        QString temp_vout_addr = "";
                        if (temp_single_vout.contains("value")) {
                            temp_money = temp_single_vout.value("value").toString();
                            vout_sum_money += temp_money.toLongLong();
                        }
                        if (temp_single_vout.contains("scriptPubKey")) {
                            QJsonObject obj_script = temp_single_vout.value("scriptPubKey").toObject();

                            if (obj_script.contains("addresses")) {
                                QJsonArray arr_addresses = obj_script.value("addresses").toArray();
                                if (arr_addresses.size() == 1) {
                                    temp_vout_addr = arr_addresses.at(0).toString("error");
                                }
                                else {
                                    qWarning("vout address parsing error");
                                }
                            }
                        }
//                        qDebug() << temp_vout_addr << ":" << temp_money;
                        mapVout_.insert(std::pair<QString,QString>(temp_vout_addr, temp_money));
                    }
                }
            }

        }
    }
    tip = vin_sum_money - vout_sum_money;
    txid_ = txid;


//    qDebug() << "vout_sum_money" << convertCoin(vout_sum_money);
//    qDebug() << "vin_sum_money" << convertCoin(vin_sum_money);
//    qDebug() << convertCoin(tip);

    /// 设置界面
    labVinTitle_->setText(QString("输入(%1)").arg(vin_size));
    labVoutTitle_->setText(QString("输出(%1)").arg(vout_size));
    labVinSumMoney_->setText(QString("%1(含手续费:%2) BTC")
                    .arg(convertCoin(vin_sum_money,true)).arg(convertCoin(tip,true)));
    labVoutSumMoney_->setText(QString("%1 BTC")
                    .arg(convertCoin(vout_sum_money,true)));

    for (std::multimap<QString, QString>::iterator iter = mapVin_.begin();
         iter != mapVin_.end(); ++iter) {
        listVinWidget_.push_back(createTransaction(iter->first,convertCoin(iter->second.toLongLong())));
    }

    for (std::multimap<QString, QString>::iterator iter = mapVout_.begin();
         iter != mapVout_.end(); ++iter) {
        listVoutWidget_.push_back(createTransaction(iter->first,convertCoin(iter->second.toLongLong())));
    }

    onUpdate();
}

void SRTransactionWidget::setViewData(
        QList<SRWithdrawCashAuditWidget::stWithdrawCash>& iter)
{

//    QString txid = "";
    double tip = 0;
    int vin_size = 0, vout_size = 0;
    double vin_sum_money = 0, vout_sum_money = 0;
    mapVin_.clear();
    mapVout_.clear();
    listVinWidget_.clear();
    listVoutWidget_.clear();

    // last transaction
    for (QList<SRWithdrawCashAuditWidget::stWithdrawCash>::iterator item = iter.begin();
         item != iter.end(); item++) {
        tip += item->tip.toDouble();
        ++vout_size;
        vout_sum_money+= item->dest_money.toDouble();
        mapVout_.insert(std::pair<QString,QString>(item->dest_addr, item->dest_money));

        for (QList<SRWithdrawCashAuditWidget::stTransaction>::iterator lasttr_iter
                                = item->last_tr.begin();
             lasttr_iter != item->last_tr.end();
             ++lasttr_iter) {
            vin_size++;
            vin_sum_money+= lasttr_iter->money.toDouble();
            mapVin_.insert(std::pair<QString,QString>(item->source_addr, lasttr_iter->money));

        }
    }

    for (QList<SRWithdrawCashAuditWidget::stWithdrawCash>::iterator item = iter.begin();
         item != iter.end(); item++) {
    }




    /// 设置界面
    labVinTitle_->setText(QString("输入(%1)").arg(vin_size));
    labVoutTitle_->setText(QString("输出(%1)").arg(vout_size));
    labVinSumMoney_->setText(QString("%1(含手续费:%2) BTC")
                    .arg(vin_sum_money).arg(tip));
    labVoutSumMoney_->setText(QString("%1 BTC")
                    .arg(vout_sum_money));

    for (std::multimap<QString, QString>::iterator iter = mapVin_.begin();
         iter != mapVin_.end(); ++iter) {
        listVinWidget_.push_back(createTransaction(iter->first,iter->second));
    }

    for (std::multimap<QString, QString>::iterator iter = mapVout_.begin();
         iter != mapVout_.end(); ++iter) {
        listVoutWidget_.push_back(createTransaction(iter->first,iter->second));
    }

    onUpdate();
}

void SRTransactionWidget::onUpdate(void)
{
    // 清理所有窗口
    while (QLayoutItem* item = layoutVin_->takeAt(0)) {
        if (item) {
            layoutVin_->removeItem(item);
            item->widget()->deleteLater();
        }
    }

    while (QLayoutItem* item = layoutVout_->takeAt(0)) {
        if (item) {
            layoutVout_->removeItem(item);
            item->widget()->deleteLater();
        }
    }

    // 添加所有窗口
    for (auto & wdgt : listVinWidget_)
        layoutVin_->addWidget(wdgt,0,Qt::AlignTop);

    for (auto & wdgt : listVoutWidget_)
        layoutVout_->addWidget(wdgt,0,Qt::AlignTop);

    // 设置窗口大小
    int isize = listVinWidget_.size();
    if (isize < listVoutWidget_.size())
        isize = listVoutWidget_.size();

    if (isize < 13) {
        setFixedHeight(isize*40 + 60);
    }
    else {
        setFixedHeight(600);
    }
    mainWdgt->setFixedHeight(isize*40 + 50);

}

void SRTransactionWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
    // 判断与源数据是否相同
    static QString last_txid = "";

    if (last_txid == txid_) {
        return ;
    }
    last_txid = txid_;



}

QWidget *SRTransactionWidget::createTransaction(const QString &addr,
                                                const QString &money,
                                                QWidget *parent)
{
    QString raddr = addr;
    int addr_length = raddr.length() - 4;
    while(addr_length > 0) {
        raddr.insert(addr_length, ' ');
        addr_length-=4;
    }


    QHBoxLayout* layout = new QHBoxLayout();
    QLabel* lab_addr = new QLabel(raddr);
    QLabel* lab_money = new QLabel(money);
    QWidget* ret_widget = new QWidget(parent);

    layout->addWidget(lab_addr);
    layout->addStretch(120);
    layout->addWidget(lab_money);

    ret_widget->setLayout(layout);

    ret_widget->setFixedSize(500,30);

    return ret_widget;
}

QString SRTransactionWidget::modifyAuditDataValueToString(QString _data)
{
    const QString& value_begin = "\"value\":";
    const QString& value_end = ",";
    QString& ret_data = _data;

    int pos = ret_data.indexOf(value_begin);

    while(pos != -1){
        // 插入 "
        ret_data.insert(pos+value_begin.length(),'\"');
        // 找到结尾,
        pos = ret_data.indexOf(value_end, pos);
        // 插入 "
        ret_data.insert(pos,'\"');

        // 找下一个开始
        pos = ret_data.indexOf(value_begin,pos);
    }
#ifdef QT_DEBUG
    qDebug() << "modifyAuditDataValueToString:" << ret_data;
#endif
    return ret_data;
}


QString SRTransactionWidget::convertCoin(qlonglong coin, bool _roundOff)
{
    if (coin == 0) {
        return "0";
    }
    bool bflag = (coin < 0) ? true : false;
    if (bflag) {
        coin = coin * -1;
    }

    QString ret_data = QString::number(coin);
    int data_length = ret_data.length();

    if (data_length < 9) {
        int i = 9 - data_length;
        while (i--)
            ret_data.push_front('0');

        data_length = ret_data.length();
    }
    ret_data.insert(data_length-8,'.');

    if (bflag)
        ret_data.push_front('-');

    if (_roundOff){
        std::string str_data = ret_data.toStdString();
        while('0' == str_data.back())
            str_data.pop_back();

        return QString::fromStdString(str_data);
    }
    else
        return ret_data;
}
